package org.agilelang.generator.cakephp;

/*
 AgileLang - A fourth generation language(http://www.agilelang.org).

 Copyright (C) 2013 Roderick Cusirramos (roderick20@hotmail.com)

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
import java.io.File;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.agilelang.object.attributes.Attribute;
import org.agilelang.object.attributes.MenuItem;
import org.agilelang.object.attributes.Reference;
import org.agilelang.object.Controller;
import org.agilelang.object.Model;
import org.agilelang.object.Project;

public class GControllerScaffoldExtend extends GControllerSimple {

    String menu = "";
    String submenu = "";

    GControllerScaffoldExtend(String path, Project project, Controller controller) {
        super(path, project, controller);
        this.path = path;
        this.controllers = project.controllers;
        this.menus = project.menus;
        this.appName = project.application.name;
        this.controller = controller;
        this.models = project.models;
        setTemplate2("cakephp");
        this.template = "bootstrap";
    }

    @Override
    public void process() {
        String textfield_reference = "";
        String model_reference = "";
        Model model = this.getModelByName(controller.model_scaffold);
        int tr = model.references.size();
        for (int j = 0; j < tr; j++) {
            Reference reference = model.references.get(j);
            textfield_reference = textfield_reference + "\t\t$this->set('" + reference.foreign_key + "',$this->" + reference.model_reference + "->find('list'));\n";
            uses = uses + ",'" + reference.model_reference + "'";
            model_reference = model_reference
                    + "\t\t'" + reference.model_reference + "' => array(\n"
                    + "\t\t\t'className' => '" + reference.model_reference + "',\n"
                    + "\t\t\t'foreignKey' => '" + reference.foreign_key + "',\n"
                    + "\t\t\t'conditions' => '',\n"
                    + "\t\t\t'fields' => '',\n"
                    + "\t\t\t'order' => ''\n"
                    + "\t\t),\n";
        }
        String views = "";
        views += view(controller.views, controller.name);
        views += viewform(controller.forms, controller.name);
        views += viewreport(controller.reports, controller.name);

        String file = readStreamTpl("cs_controller_ex.php.tpl");
        file = file.replace("//views_str//", views);

        file = file.replace("//nameClass//", controller.name);
        file = file.replace("//nameClass_Singularize//", controller.model_scaffold);

        file = file.replace("//nameclass//", controller.name.toLowerCase());
        file = file.replace("//nameclass_singularize//", controller.model_scaffold.toLowerCase());

        file = file.replace("//nameCaption//", controller.name);
        file = file.replace("//uses//", "\tpublic $uses = array('" + controller.model_scaffold + "'" + uses + ");\n");
        file = file.replace("//textfield_reference//", textfield_reference);

        search_menu4(controller.name, "crud");
        file = file.replace("//menu//", menu.toLowerCase());
        file = file.replace("//menuitem//", submenu.toLowerCase());

        createfile("Controller/" + controller.name + "Controller.php", path, file);
        createDirectory(path + File.separator + "view/" + controller.name);

        index(controller.name, controller.caption, model.name, model.attributes, model.references);
//        read(controller.name, model.caption, model.name, model.attributes, model.references);
        update(controller.name, controller.caption, model.name, model.attributes, model.references);


    }

    private void index(String name, String nameCaption, String name_singularize, List<Attribute> attrs, List<Reference> references) {
        int tt = attrs.size();
        String td_attrs = "";
        String th_attrs = "";

        if (!this.controller.attributesIndex.equals("")) {
            String[] attr_str = this.controller.attributesIndex.split(",");
            int t = attr_str.length;
            for (int j = 0; j < t; j++) {
                Attribute attr = search_attr(attr_str[j].trim(), attrs);
                if (attr.name.endsWith("_id")) {
                    int tr = references.size();
                    for (int jj = 0; jj < tr; jj++) {
                        Reference reference = references.get(jj);
                        if (attr.name.equals(reference.foreign_key)) {
                            td_attrs = td_attrs + "\t\t\t<td><?php echo $" + name_singularize.toLowerCase() + "['" + reference.model_reference + "']['" + reference.field_reference + "']; ?>&nbsp;</td> \r\n";
                            break;
                        }
                    }
                } else {
                    if (attr.type.equals("boolean")) {
                        td_attrs = td_attrs + "\t\t\t<td><?php echo $" + name_singularize.toLowerCase() + "['" + name_singularize + "']['" + attr.name + "'] == '1' ? 'Si' :'No'; ?>&nbsp;</td> \r\n";
                    } else {
                        td_attrs = td_attrs + "\t\t\t<td><?php echo $" + name_singularize.toLowerCase() + "['" + name_singularize + "']['" + attr.name + "']; ?>&nbsp;</td> \r\n";
                    }
                }



                th_attrs = th_attrs + "\t\t\t<th><?php echo $this->Paginator->sort('" + attr.caption + "');?></th>\r\n";
            }

        } else {
            Collections.sort(attrs, new CustomComparator2());
            for (int j = 0; j < tt; j++) {
                Attribute attr = attrs.get(j);
                if (attr.name.endsWith("_id")) {
                    int tr = references.size();
                    for (int jj = 0; jj < tr; jj++) {
                        Reference reference = references.get(jj);
                        if (attr.name.equals(reference.foreign_key)) {
                            td_attrs = td_attrs + "\t\t\t<td><?php echo $" + name_singularize.toLowerCase() + "['" + reference.model_reference + "']['" + reference.field_reference + "']; ?>&nbsp;</td> \r\n";
                            break;
                        }
                    }
                } else {
                    if (attr.type.equals("boolean")) {
                        td_attrs = td_attrs + "\t\t\t<td><?php echo $" + name_singularize.toLowerCase() + "['" + name_singularize + "']['" + attr.name + "'] == '1' ? 'Si' :'No'; ?>&nbsp;</td> \r\n";
                    } else {
                        td_attrs = td_attrs + "\t\t\t<td><?php echo $" + name_singularize.toLowerCase() + "['" + name_singularize + "']['" + attr.name + "']; ?>&nbsp;</td> \r\n";
                    }
                }



                th_attrs = th_attrs + "\t\t\t<th><?php echo $this->Paginator->sort('" + attr.caption + "');?></th>\r\n";
            }

        }
        String file = readStreamTpl("cs_index_ex.html.tpl");
        //file = file.replace("//appName//", this.appName);
        file = file.replace("//nameClass_pluralize//", name);
        file = file.replace("//nameCaption//", nameCaption);
        file = file.replace("//nameClass_singularize//", name_singularize);
        file = file.replace("//nameclass_pluralize//", name.toLowerCase());
        file = file.replace("//nameclass_singularize//", name_singularize.toLowerCase());
        file = file.replace("//td_attrs//", td_attrs);
        file = file.replace("//th_attrs//", th_attrs);
        createfile("view/" + name.toLowerCase() + "/index.ctp", path, file);
    }

    public void update(String name, String nameCaption, String name_singularize, List<Attribute> attrs, List<Reference> references) {
        Collections.sort(attrs, new CustomComparator2());

        String textfield_attrs = "";
        if (!this.controller.attributesIndex.equals("")) {
            String[] attr_str = this.controller.attributesIndex.split(",");
            String[] attr_str_up = this.controller.attributesUpdate.split(",");
            int t = attr_str.length;
            int tt = attr_str_up.length;
            boolean fl = false;
            for (int j = 0; j < t; j++) {
                Attribute attr = search_attr(attr_str[j].trim(), attrs);
                fl = true;
                for (int jj = 0; jj < tt; jj++) {
                    if (attr_str_up[jj].trim().equals(attr.name)) {
                        fl = false;
                    }
                }
//                String NameAtrr = attr.name.substring(0, 1).toUpperCase() + attr.name.substring(1, attr.name.length());
                if (fl) {
                    if (attr.name.endsWith("_id")) {
                        textfield_attrs = textfield_attrs + "<?php echo $this->Form->input('" + attr.name + "', array('label'=>array('text'=>'" + attr.caption + "','class' => 'control-label'),'type' => 'select', 'disabled' => 'disabled','options' => $" + attr.name + "));?>\r\n";
                    } else {
                        //textfield_attrs = textfield_attrs + "\techo $this->Form->input('" + attr.name + "');\r\n";
                        textfield_attrs = textfield_attrs + "<?php echo $this->Form->input('" + attr.name + "', array('label'=>array('text'=>'" + attr.caption + "','class' => 'control-label'),'disabled' => 'disabled','placeholder' => '" + attr.caption + "')); ?>\r\n";

                    }
                }

            }
        }
        if (!this.controller.attributesUpdate.equals("")) {
            String[] attr_str = this.controller.attributesUpdate.split(",");
            int t = attr_str.length;
            for (int j = 0; j < t; j++) {
                Attribute attr = search_attr(attr_str[j].trim(), attrs);
//                String NameAtrr = attr.name.substring(0, 1).toUpperCase() + attr.name.substring(1, attr.name.length());

                if (attr.name.endsWith("_id")) {
                    textfield_attrs = textfield_attrs + "<?php echo $this->Form->input('" + attr.name + "', array('label'=>array('text'=>'" + attr.caption + "','class' => 'control-label'),'type' => 'select', 'options' => $" + attr.name + "));?>\r\n";
                } else {
                    //textfield_attrs = textfield_attrs + "\techo $this->Form->input('" + attr.name + "');\r\n";
                    textfield_attrs = textfield_attrs + "<?php echo $this->Form->input('" + attr.name + "', array('label'=>array('text'=>'" + attr.caption + "','class' => 'control-label'),'placeholder' => '" + attr.caption + "')); ?>\r\n";

                }
            }
        }

        String file = readStreamTpl("cs_update.html.tpl");
        file = file.replace("//appName//", this.appName);
        file = file.replace("//nameClass_pluralize//", name);
        file = file.replace("//nameCaption//", nameCaption);
        file = file.replace("//nameClass_singularize//", name_singularize);
        file = file.replace("//nameclass_pluralize//", name.toLowerCase());
        file = file.replace("//nameclass_singularize//", name_singularize.toLowerCase());
        file = file.replace("//textfield_attrs//", textfield_attrs);
        createfile("view/" + name.toLowerCase() + "/edit.ctp", path, file);
    }

    private void search_menu4(String controller, String view) {
        int t = menus.size();
        for (int i = 0; i < t; i++) {
            int tt = menus.get(i).menuitems.size();
            for (int ii = 0; ii < tt; ii++) {
                MenuItem menuitem = menus.get(i).menuitems.get(ii);
                if (menuitem.controller.equals(controller) && menuitem.action.equals(view)) {
                    menu = menus.get(i).name;
                    submenu = menuitem.name;
                }
            }
        }
    }

    private String search_menu_view(String controller, String view) {
        String menu = TAB + "$this->set('menu', '');\r\n"
                + TAB + "$this->set('submenu', '');\r\n"
                + TAB + "$this->set('cakeDescription', '');\r\n"
                + TAB + "$this->set('title_for_layout', '');\r\n";
        int t = menus.size();
        for (int i = 0; i < t; i++) {
            int tt = menus.get(i).menuitems.size();
            for (int ii = 0; ii < tt; ii++) {
                MenuItem menuitem = menus.get(i).menuitems.get(ii);
                String action_item = "";
                if (menuitem.controller.equals(controller) && menuitem.action.equals(view)) {
                    menu = TAB + "$this->set('menu', '" + menus.get(i).name.toLowerCase() + "');\r\n"
                            + TAB + "$this->set('submenu', '" + menuitem.name.toLowerCase() + "');\r\n"
                            + TAB + "$this->set('cakeDescription', '');\r\n"
                            + TAB + "$this->set('title_for_layout', '');\r\n";
                }
            }
        }
        return menu;
    }

    public class CustomComparator2 implements Comparator<Attribute> {

        @Override
        public int compare(Attribute o1, Attribute o2) {
            return o1.item.compareTo(o2.item);
        }
    }

    public Attribute search_attr(String name, List<Attribute> list) {
        int tt = list.size();
        for (int j = 0; j < tt; j++) {
            Attribute attr = list.get(j);
            if (attr.name.equals(name)) {
                return attr;
            }
        }
        return null;
    }
}